/*
 * @Author: greyqiu greyqiu@163.com
 * @Date: 2023-06-27 16:56:34
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-07-20 10:13:16
 * @FileName: easy_timer.h
 * @Description: 
 * 
 * Copyright (c) 2023 by GreyQiu, All Rights Reserved. 
 */

#ifndef EASY_TIMER_H__
#define EASY_TIMER_H__
#include <stddef.h>
#include <stdbool.h>
#include "easy_timer_config.h"

/**
 * @description: easy_timer回调函数指针定义
 */
typedef void (*easy_timer_timeout_handler_t)(void);

/**
 * @description: easy_timer触发模式定义
 */
typedef enum
{
    EASY_TIMER_MODE_SINGLE_SHOT, // 单次触发模式
    EASY_TIMER_MODE_REPEATED     // 重复触发模式
} easy_timer_mode_t;

/**
 * @description: easy_timer对象结构
 */
typedef struct easy_timer_struct
{
    bool        bDelete; // 删除标志
    uint64_t    counter; // 当前计数值
    uint32_t    tickLast; // 上一拍计数值
    uint64_t    period; // 触发周期
    easy_timer_mode_t     mode; // 触发模式
    uint8_t     pending; // 挂起标志
    easy_timer_timeout_handler_t    cb; // 触发后回调函数指针
    struct easy_timer_struct* last; // 上一个节点
    struct easy_timer_struct* next; // 下一个节点
} easy_timer_t;

typedef easy_timer_t * easy_timer_id_t;

/**
 * @description: easy_timer对象结构
 */
#define TICKS_1MS (EASY_TIMER_CLOCK_FREQ / 1000) // 1ms对应的ticks值

/**
 * @description: 使用宏定义一个easy_timer对象
 */
#define EASY_TIMER_DEF(timer_id)               \
    static easy_timer_t timer_id##_data = {     \
            .bDelete = true,                    \
            .pending = true,                    \
    };                                          \
    static easy_timer_id_t timer_id = &timer_id##_data


void easy_timer_init(void);
void easy_timer_create(easy_timer_id_t p_timer_id);

void easy_timer_start(easy_timer_id_t p_timer_id, 
                     uint32_t period, 
                     easy_timer_mode_t mode,
                     easy_timer_timeout_handler_t timeout_handler
                    );

void easy_timer_stop(easy_timer_id_t timer_id);
void easy_timer_delete(easy_timer_id_t  p_timer_id);
void easy_timer_execute(void);
void easy_timer_restart(easy_timer_id_t timer_id);

#endif // EASY_TIMER_H__
